package rjeutsky.database.jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;

import rjeutsky.database.interfaces.CRUDDomainRepository;
import rjeutsky.models.Publication;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;

public class PublicationDomainRepository implements CRUDDomainRepository <Publication> {

	private static final String CREATE_SQL = "INSERT INTO Publication (Id, Name, Price) VALUES (?, ?, ?)";
	private static final String CREATE_NO_ID_SQL = "INSERT INTO Publication (Name, Price) VALUES (?, ?)";
	private static final String READ_SQL = "SELECT Id, Name, Price FROM Publication WHERE Id = ?";
	private static final String UPDATE_SQL = "UPDATE Publication SET Name=?, Price=? WHERE Id=?";
	private static final String QUERY_SQL = "SELECT Id, Name, Price FROM Publication";
	
	private PreparedStatement createStatement;
	private PreparedStatement createNoIdStatement;
	private PreparedStatement readStatement;
	private PreparedStatement updateStatement;
	private PreparedStatement queryStatement;
	
	public PublicationDomainRepository(Connection connection) throws SQLException {
		createStatement = connection.prepareStatement(CREATE_SQL, PreparedStatement.RETURN_GENERATED_KEYS);
		createNoIdStatement = connection.prepareStatement(CREATE_NO_ID_SQL, PreparedStatement.RETURN_GENERATED_KEYS);
		readStatement = connection.prepareStatement(READ_SQL);
		updateStatement = connection.prepareStatement(UPDATE_SQL);
		queryStatement = connection.prepareStatement(QUERY_SQL);
	}
	
	@Override
	public void create(Publication item) throws SQLException {
		if (item.getId() == null) {
			createNoIdStatement.setString(1, item.getName());
			createNoIdStatement.setLong(2, item.getPrice());
			createNoIdStatement.executeUpdate();
			ResultSet generatedKeys = createNoIdStatement.getGeneratedKeys();
			generatedKeys.next();
			item.setId(generatedKeys.getLong(1));
		} 
		else {
			createStatement.setLong(1, item.getId());
			createStatement.setString(2, item.getName());
			createStatement.setLong(3, item.getPrice());
			createStatement.executeUpdate();
		}
	}

	@Override
	public void delete(long id) {
		// TODO Auto-generated method stub
		throw new NotImplementedException();
	}

	@Override
	public Publication read(long id) throws SQLException {
		readStatement.setLong(1, id);
		ResultSet resultSet = readStatement.executeQuery();
		Publication publication = null;
		while (resultSet.next()) {
			publication = new Publication();
			publication.setId(resultSet.getLong(1));
			publication.setName(resultSet.getString(2));
			publication.setPrice(resultSet.getLong(3));
		}
		
		return publication;
	}

	@Override
	public void update(Publication item) throws SQLException {
		updateStatement.setString(1, item.getName());
		updateStatement.setLong(2, item.getPrice());
		updateStatement.setLong(3, item.getId());
		updateStatement.executeUpdate();
	}

	@Override
	public List<Publication> query() throws SQLException {
		List<Publication> publications = new LinkedList<Publication>();
		ResultSet resultSet = queryStatement.executeQuery();
		while (resultSet.next()) {
			Publication publication = new Publication();
			publication.setId(resultSet.getLong(1));
			publication.setName(resultSet.getString(2));
			publication.setPrice(resultSet.getLong(3));
			publications.add(publication);
		}
		
		return publications;
	}

}
